package com.nightpiter.model.objects;

import com.nightpiter.model.exceptions.TimeFormatException;

/**
 * Time class
 * 
 * working with Time typed values
 * 
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 * @author Ilya Shourigyn (honorik@gmail.com)
 * 
 */

public class Time {

	private int seconds;
	private int minutes;
	private int hours;

	/**
	 * @param hours -
	 *            Hours
	 * @param minutes -
	 *            Minutes
	 * @param seconds -
	 *            Seconds
	 */
	public Time(int hours, int minutes, int seconds) {
		this.seconds = seconds % 60;
		this.minutes = (minutes % 60 + seconds / 60) % 60;
		this.hours = hours + seconds / 3600 + minutes / 60;
	}

	/**
	 * 
	 * @param seconds -
	 *            Time in seconds
	 */
	public Time(int seconds) {
		this.seconds = seconds % 60;
		this.minutes = (seconds / 60) % 60;
		this.hours = hours + seconds / 3600;
	}

	/**
	 * 
	 * @param strTime
	 *            time in format "hh::mm::ss" or "mm::ss" or "ss"
	 * @throws TimeFormatException -
	 *             in case of wrong time format
	 */
	public Time(String strTime) throws TimeFormatException {

		String[] strTimeParts = strTime.split(":");

		switch (strTimeParts.length) {
		case 1:
			seconds = Integer.parseInt(strTimeParts[0]);
			break;
		case 2:
			minutes = Integer.parseInt(strTimeParts[0]);
			seconds = Integer.parseInt(strTimeParts[1]);
			break;
		case 3:
			hours = Integer.parseInt(strTimeParts[0]);
			minutes = Integer.parseInt(strTimeParts[1]);
			seconds = Integer.parseInt(strTimeParts[2]);
			break;
		default:
			throw new TimeFormatException();
		}

	}

	/**
	 * hh - hours always with 2 chars mm-minutes always with 2 chars ss-seconds
	 * always with 2 chars 0hh(<text>) - print text in () and hours only if not
	 * null 0mm(<text>) - print text in () and hours only if not null 0ss(<text>) -
	 * print text in () and hours only if not null
	 * 
	 * @param format
	 *            string with "hh", "mm" and "ss" in place of hours, minutes and
	 *            seconds
	 * @return formated time in string
	 */
	public String toFormatedString(String format) {

		format = removeTextIfTimeIsNullOrReplace(format, "0hh", hours);
		format = removeTextIfTimeIsNullOrReplace(format, "0mm", minutes);
		format = removeTextIfTimeIsNullOrReplace(format, "0ss", seconds);
		format = format.replaceAll("hh", this.formatIntString(this.hours));
		format = format.replaceAll("mm", this.formatIntString(this.minutes));
		format = format.replaceAll("ss", this.formatIntString(this.seconds));
		// format=format.replaceAll("h", Integer.toString(this.hours));
		// format=format.replaceAll("m", Integer.toString(this.minutes));
		// format=format.replaceAll("s", Integer.toString(this.seconds));
		return format;
	}

	/**
	 * removes text and time if time is null
	 * 
	 * @param str
	 *            string with substrings to replace
	 * @param format -
	 *            substring to replace
	 * @param time
	 *            time to insert instead of format
	 * @return formated string
	 */
	private String removeTextIfTimeIsNullOrReplace(String str, String format,
			int time) {
		format += "(";
		str += "";
		while (str.indexOf(format) != -1) {
			int begin = str.indexOf(format);
			int end = str.indexOf(')', begin);
			if (time == 0) {
				if (begin != -1) {
					if (end != -1) {
						str = str.substring(0, begin) + str.substring(end + 1);
					} else {
						str = str.substring(0, end) + str.substring(end + 1);
						;
						str = str.replaceFirst(format, "");
					}
				}
			} else {
				str = str.replaceFirst(format, this.formatIntString(time));
			}
		}
		return str;
	}

	/**
	 * @param format
	 *            string with "hh", "mm" and "ss" in place of hours, minutes and
	 *            seconds
	 * @return formated time in string
	 */

	public static String toFormatedString(String format, int timeInSeconds) {
		Time time = new Time(timeInSeconds);
		return time.toFormatedString(format);
	}

	/**
	 * Represent Time as string in format "h:mm:ss" if Hours is more then null,
	 * and "mm:ss" in other way
	 */
	public String toString() {
		String result = "";
		if (hours != 0) {
			result += hours + ":";
		}
		result += this.formatIntString(minutes) + ":";
		result += this.formatIntString(seconds);
		return result;
	}

	private String formatIntString(int integer) {
		String result = "";
		if (integer < 10) {
			result += "0";
		}
		result += Integer.toString(integer);
		return result;
	}

	public int getHours() {
		return this.hours;
	}

	public int getMinutes() {
		return this.minutes;
	}

	public int getSeconds() {
		return this.seconds;
	}

	/**
	 * 
	 * @param strTime
	 *            time in format "hh::mm::ss" or "mm::ss" or "ss"
	 * @return time in seconds
	 * @throws TimeFormatException -
	 *             in case of wrong time format
	 */
	public static int stringToInt(String strTime) throws TimeFormatException {
		Time time = new Time(strTime);
		return time.hours * 3600 + time.minutes * 60 + time.seconds;
	}

}
